Ruby 日記 33日目: <=>演算子
次のコードを実行するとどうなりますか
code:gold/ex33/main.rb
class Company
attr_reader :id
attr_accessor :name
def initialize id, name
@id = id
@name = name
end
def to_s
"#{id}:#{name}"
end
def <=> other
self.id <=> other.id
end
end
companies = []
companies << Company.new(2, 'Liberyfish')
companies << Company.new(3, 'Freefish')
companies << Company.new(1, 'Freedomfish')
companies.sort
companies.each do |e|
puts e
end
選択肢:
code:txt
1:Freedomfish
3:Freefish
2:Liberyfish
code:txt
2:Liberyfish
1:Freedomfish
3:Freefish
code:txt
2:Liberyfish
3:Freefish
1:Freedomfish
code:txt
3:Freefish
1:Freedomfish
2:Liberyfish
解説:
配列の内容をソートします。要素同士の比較は <=> 演算子を使って行います。sort はソートされた配列を生成して返します。
重要なポイントは2つ
比較は <=> 演算子を使っていること
ソートされた新たな配列を作って返すこと = 元の配列自身には影響がない(非破壊的である)こと
今回の問題では、Companyクラスにインスタンスメソッド<=>が定義されており、idというattributeの値によってsortされることになる。
しかし、このsortは非破壊的な操作であるため、companies自体の並び順は変わっていない。
よって正解は↓
code:sh
# ruby gold/ex33/main.rb
2:Liberyfish
3:Freefish
1:Freedomfish
/icons/hr.icon
もしもsortではなくsort!をしていたら
code:rb
class Company
attr_reader :id
attr_accessor :name
def initialize id, name
@id = id
@name = name
end
def to_s
"#{id}:#{name}"
end
def <=> other
self.id <=> other.id
end
end
companies = []
companies << Company.new(2, 'Liberyfish')
companies << Company.new(3, 'Freefish')
companies << Company.new(1, 'Freedomfish')
companies.sort!
companies.each do |e|
puts e
end
code:sh
# ruby gold/ex33/sample01.rb
1:Freedomfish
2:Liberyfish
3:Freefish
idの昇順に並ぶ〜
/icons/hr.icon
もしもidじゃなくてnameで比較していたら
code:gold/ex33/sample02.rb
class Company
attr_reader :id
attr_accessor :name
def initialize id, name
@id = id
@name = name
end
def to_s
"#{id}:#{name}"
end
def <=> other
self.name <=> other.name
end
end
companies = []
companies << Company.new(2, 'Liberyfish')
companies << Company.new(3, 'Freefish')
companies << Company.new(1, 'Freedomfish')
companies.sort!
companies.each do |e|
puts e
end
code:sh
# ruby gold/ex33/sample02.rb
1:Freedomfish
3:Freefish
2:Liberyfish
nameの昇順に並ぶ〜〜
/icons/hr.icon
self と other を ASCII コード順で比較して、 self が大きい時には 1、等しい時には 0、小さい時には -1 を返します。 このメソッドは Comparable モジュールのメソッドを実装するために使われます。
とのこと。
一般に<=> メソッドは self <=> other という形で使われ、selfとotherをなんらかの方法で比較して、 selfが大きい時には1、等しい時には0、小さい時には-1を返す。
self <=> other は
self が other より大きいなら正の整数
self と other が等しいなら 0
self が other より小さいなら負の整数
self と other が比較できない場合は nil
をそれぞれ返すことが期待されています。
Comparableモジュールにちゃんと定義してあったね〜。比較できない時はnilを返すのね、ふむふむ。